home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Belgian Amiga Club - ADF Collection
/
BS1 part 65.zip
/
BS1 part 65
/
Protracker v2.1a.adf
/
PT-Play.s
< prev
next >
Wrap
Text File
|
1992-04-13
|
22KB
|
816 lines
;**************************************************
;* ----- Protracker V2.1A Playroutine ----- *
;* Peter "CRAYON" Hanning / Mushroom Studios 1992 *
;* Vinterstigen 12, 14440 Ronninge, Sweden *
;**************************************************
; VBlank Version 2:
; Call mt_init to initialize the routine, then call mt_music on
; each vertical blank (50 Hz). To end the song and turn off all
; voices, call mt_end.
; This playroutine is not very fast, optimized or well commented,
; but all the new commands in PT2.1A should work.
; If it's not good enough, you'll have to change it yourself.
; We'll try to write a faster routine soon...
; Changes from V1.0C playroutine:
; - Vibrato depth changed to be compatible with Noisetracker 2.0.
; You'll have to double all vib. depths on old PT modules.
; - Funk Repeat changed to Invert Loop.
; - Period set back earlier when stopping an effect.
DMAWait = 300 ; Set this as low as possible without losing low notes.
n_note EQU 0 ; W
n_cmd EQU 2 ; W
n_cmdlo EQU 3 ; B
n_start EQU 4 ; L
n_length EQU 8 ; W
n_loopstart EQU 10 ; L
n_replen EQU 14 ; W
n_period EQU 16 ; W
n_finetune EQU 18 ; B
n_volume EQU 19 ; B
n_dmabit EQU 20 ; W
n_toneportdirec EQU 22 ; B
n_toneportspeed EQU 23 ; B
n_wantedperiod EQU 24 ; W
n_vibratocmd EQU 26 ; B
n_vibratopos EQU 27 ; B
n_tremolocmd EQU 28 ; B
n_tremolopos EQU 29 ; B
n_wavecontrol EQU 30 ; B
n_glissfunk EQU 31 ; B
n_sampleoffset EQU 32 ; B
n_pattpos EQU 33 ; B
n_loopcount EQU 34 ; B
n_funkoffset EQU 35 ; B
n_wavestart EQU 36 ; L
n_reallength EQU 40 ; W
mt_init LEA mt_data,A0
MOVE.L A0,mt_SongDataPtr
MOVE.L A0,A1
LEA 952(A1),A1
MOVEQ #127,D0
MOVEQ #0,D1
mtloop MOVE.L D1,D2
SUBQ.W #1,D0
mtloop2 MOVE.B (A1)+,D1
CMP.B D2,D1
BGT.S mtloop
DBRA D0,mtloop2
ADDQ.B #1,D2
LEA mt_SampleStarts(PC),A1
ASL.L #8,D2
ASL.L #2,D2
ADD.L #1084,D2
ADD.L A0,D2
MOVE.L D2,A2
MOVEQ #30,D0
mtloop3 CLR.L (A2)
MOVE.L A2,(A1)+
MOVEQ #0,D1
MOVE.W 42(A0),D1
ASL.L #1,D1
ADD.L D1,A2
ADD.L #30,A0
DBRA D0,mtloop3
OR.B #2,$BFE001
MOVE.B #6,mt_speed
CLR.B mt_counter
CLR.B mt_SongPos
CLR.W mt_PatternPos
mt_end CLR.W $DFF0A8
CLR.W $DFF0B8
CLR.W $DFF0C8
CLR.W $DFF0D8
MOVE.W #$F,$DFF096
RTS
mt_music
MOVEM.L D0-D4/A0-A6,-(SP)
ADDQ.B #1,mt_counter
MOVE.B mt_counter(PC),D0
CMP.B mt_speed(PC),D0
BLO.S mt_NoNewNote
CLR.B mt_counter
TST.B mt_PattDelTime2
BEQ.S mt_GetNewNote
BSR.S mt_NoNewAllChannels
BRA mt_dskip
mt_NoNewNote
BSR.S mt_NoNewAllChannels
BRA mt_NoNewPosYet
mt_NoNewAllChannels
LEA $DFF0A0,A5
LEA mt_chan1temp(PC),A6
BSR mt_CheckEfx
LEA $DFF0B0,A5
LEA mt_chan2temp(PC),A6
BSR mt_CheckEfx
LEA $DFF0C0,A5
LEA mt_chan3temp(PC),A6
BSR mt_CheckEfx
LEA $DFF0D0,A5
LEA mt_chan4temp(PC),A6
BRA mt_CheckEfx
mt_GetNewNote
MOVE.L mt_SongDataPtr(PC),A0
LEA 12(A0),A3
LEA 952(A0),A2 ;pattpo
LEA 1084(A0),A0 ;patterndata
MOVEQ #0,D0
MOVEQ #0,D1
MOVE.B mt_SongPos(PC),D0
MOVE.B (A2,D0.W),D1
ASL.L #8,D1
ASL.L #2,D1
ADD.W mt_PatternPos(PC),D1
CLR.W mt_DMACONtemp
LEA $DFF0A0,A5
LEA mt_chan1temp(PC),A6
BSR.S mt_PlayVoice
LEA $DFF0B0,A5
LEA mt_chan2temp(PC),A6
BSR.S mt_PlayVoice
LEA $DFF0C0,A5
LEA mt_chan3temp(PC),A6
BSR.S mt_PlayVoice
LEA $DFF0D0,A5
LEA mt_chan4temp(PC),A6
BSR.S mt_PlayVoice
BRA mt_SetDMA
mt_PlayVoice
TST.L (A6)
BNE.S mt_plvskip
BSR mt_PerNop
mt_plvskip
MOVE.L (A0,D1.L),(A6)
ADDQ.L #4,D1
MOVEQ #0,D2
MOVE.B n_cmd(A6),D2
AND.B #$F0,D2
LSR.B #4,D2
MOVE.B (A6),D0
AND.B #$F0,D0
OR.B D0,D2
TST.B D2
BEQ mt_SetRegs
MOVEQ #0,D3
LEA mt_SampleStarts(PC),A1
MOVE D2,D4
SUBQ.L #1,D2
ASL.L #2,D2
MULU #30,D4
MOVE.L (A1,D2.L),n_start(A6)
MOVE.W (A3,D4.L),n_length(A6)
MOVE.W (A3,D4.L),n_reallength(A6)
MOVE.B 2(A3,D4.L),n_finetune(A6)
MOVE.B 3(A3,D4.L),n_volume(A6)
MOVE.W 4(A3,D4.L),D3 ; Get repeat
TST.W D3
BEQ.S mt_NoLoop
MOVE.L n_start(A6),D2 ; Get start
ASL.W #1,D3
ADD.L D3,D2 ; Add repeat
MOVE.L D2,n_loopstart(A6)
MOVE.L D2,n_wavestart(A6)
MOVE.W 4(A3,D4.L),D0 ; Get repeat
ADD.W 6(A3,D4.L),D0 ; Add replen
MOVE.W D0,n_length(A6)
MOVE.W 6(A3,D4.L),n_replen(A6) ; Save replen
MOVEQ #0,D0
MOVE.B n_volume(A6),D0
MOVE.W D0,8(A5) ; Set volume
BRA.S mt_SetRegs
mt_NoLoop
MOVE.L n_start(A6),D2
ADD.L D3,D2
MOVE.L D2,n_loopstart(A6)
MOVE.L D2,n_wavestart(A6)
MOVE.W 6(A3,D4.L),n_replen(A6) ; Save replen
MOVEQ #0,D0
MOVE.B n_volume(A6),D0
MOVE.W D0,8(A5) ; Set volume
mt_SetRegs
MOVE.W (A6),D0
AND.W #$0FFF,D0
BEQ mt_CheckMoreEfx ; If no note
MOVE.W 2(A6),D0
AND.W #$0FF0,D0
CMP.W #$0E50,D0
BEQ.S mt_DoSetFineTune
MOVE.B 2(A6),D0
AND.B #$0F,D0
CMP.B #3,D0 ; TonePortamento
BEQ.S mt_ChkTonePorta
CMP.B #5,D0
BEQ.S mt_ChkTonePorta
CMP.B #9,D0 ; Sample Offset
BNE.S mt_SetPeriod
BSR mt_CheckMoreEfx
BRA.S mt_SetPeriod
mt_DoSetFineTune
BSR mt_SetFineTune
BRA.S mt_SetPeriod
mt_ChkTonePorta
BSR mt_SetTonePorta
BRA mt_CheckMoreEfx
mt_SetPeriod
MOVEM.L D0-D1/A0-A1,-(SP)
MOVE.W (A6),D1
AND.W #$0FFF,D1
LEA mt_PeriodTable(PC),A1
MOVEQ #0,D0
MOVEQ #36,D7
mt_ftuloop
CMP.W (A1,D0.W),D1
BHS.S mt_ftufound
ADDQ.L #2,D0
DBRA D7,mt_ftuloop
mt_ftufound
MOVEQ #0,D1
MOVE.B n_finetune(A6),D1
MULU #36*2,D1
ADD.L D1,A1
MOVE.W (A1,D0.W),n_period(A6)
MOVEM.L (SP)+,D0-D1/A0-A1
MOVE.W 2(A6),D0
AND.W #$0FF0,D0
CMP.W #$0ED0,D0 ; Notedelay
BEQ mt_CheckMoreEfx
MOVE.W n_dmabit(A6),$DFF096
BTST #2,n_wavecontrol(A6)
BNE.S mt_vibnoc
CLR.B n_vibratopos(A6)
mt_vibnoc
BTST #6,n_wavecontrol(A6)
BNE.S mt_trenoc
CLR.B n_tremolopos(A6)
mt_trenoc
MOVE.L n_start(A6),(A5) ; Set start
MOVE.W n_length(A6),4(A5) ; Set length
MOVE.W n_period(A6),D0
MOVE.W D0,6(A5) ; Set period
MOVE.W n_dmabit(A6),D0
OR.W D0,mt_DMACONtemp
BRA mt_CheckMoreEfx
mt_SetDMA
MOVE.W #300,D0
mt_WaitDMA
DBRA D0,mt_WaitDMA
MOVE.W mt_DMACONtemp(PC),D0
OR.W #$8000,D0
MOVE.W D0,$DFF096
MOVE.W #300,D0
mt_WaitDMA2
DBRA D0,mt_WaitDMA2
LEA $DFF000,A5
LEA mt_chan4temp(PC),A6
MOVE.L n_loopstart(A6),$D0(A5)
MOVE.W n_replen(A6),$D4(A5)
LEA mt_chan3temp(PC),A6
MOVE.L n_loopstart(A6),$C0(A5)
MOVE.W n_replen(A6),$C4(A5)
LEA mt_chan2temp(PC),A6
MOVE.L n_loopstart(A6),$B0(A5)
MOVE.W n_replen(A6),$B4(A5)
LEA mt_chan1temp(PC),A6
MOVE.L n_loopstart(A6),$A0(A5)
MOVE.W n_replen(A6),$A4(A5)
mt_dskip
ADD.W #16,mt_PatternPos
MOVE.B mt_PattDelTime,D0
BEQ.S mt_dskc
MOVE.B D0,mt_PattDelTime2
CLR.B mt_PattDelTime
mt_dskc TST.B mt_PattDelTime2
BEQ.S mt_dska
SUBQ.B #1,mt_PattDelTime2
BEQ.S mt_dska
SUB.W #16,mt_PatternPos
mt_dska TST.B mt_PBreakFlag
BEQ.S mt_nnpysk
SF mt_PBreakFlag
MOVEQ #0,D0
MOVE.B mt_PBreakPos(PC),D0
CLR.B mt_PBreakPos
LSL.W #4,D0
MOVE.W D0,mt_PatternPos
mt_nnpysk
CMP.W #1024,mt_PatternPos
BLO.S mt_NoNewPosYet
mt_NextPosition
MOVEQ #0,D0
MOVE.B mt_PBreakPos(PC),D0
LSL.W #4,D0
MOVE.W D0,mt_PatternPos
CLR.B mt_PBreakPos
CLR.B mt_PosJumpFlag
ADDQ.B #1,mt_SongPos
AND.B #$7F,mt_SongPos
MOVE.B mt_SongPos(PC),D1
MOVE.L mt_SongDataPtr(PC),A0
CMP.B 950(A0),D1
BLO.S mt_NoNewPosYet
CLR.B mt_SongPos
mt_NoNewPosYet
TST.B mt_PosJumpFlag
BNE.S mt_NextPosition
MOVEM.L (SP)+,D0-D4/A0-A6
RTS
mt_CheckEfx
BSR mt_UpdateFunk
MOVE.W n_cmd(A6),D0
AND.W #$0FFF,D0
BEQ.S mt_PerNop
MOVE.B n_cmd(A6),D0
AND.B #$0F,D0
BEQ.S mt_Arpeggio
CMP.B #1,D0
BEQ mt_PortaUp
CMP.B #2,D0
BEQ mt_PortaDown
CMP.B #3,D0
BEQ mt_TonePortamento
CMP.B #4,D0
BEQ mt_Vibrato
CMP.B #5,D0
BEQ mt_TonePlusVolSlide
CMP.B #6,D0
BEQ mt_VibratoPlusVolSlide
CMP.B #$E,D0
BEQ mt_E_Commands
SetBack MOVE.W n_period(A6),6(A5)
CMP.B #7,D0
BEQ mt_Tremolo
CMP.B #$A,D0
BEQ mt_VolumeSlide
mt_Return2
RTS
mt_PerNop
MOVE.W n_period(A6),6(A5)
RTS
mt_Arpeggio
MOVEQ #0,D0
MOVE.B mt_counter(PC),D0
DIVS #3,D0
SWAP D0
CMP.W #0,D0
BEQ.S mt_Arpeggio2
CMP.W #2,D0
BEQ.S mt_Arpeggio1
MOVEQ #0,D0
MOVE.B n_cmdlo(A6),D0
LSR.B #4,D0
BRA.S mt_Arpeggio3
mt_Arpeggio1
MOVEQ #0,D0
MOVE.B n_cmdlo(A6),D0
AND.B #15,D0
BRA.S mt_Arpeggio3
mt_Arpeggio2
MOVE.W n_period(A6),D2
BRA.S mt_Arpeggio4
mt_Arpeggio3
ASL.W #1,D0
MOVEQ #0,D1
MOVE.B n_finetune(A6),D1
MULU #36*2,D1
LEA mt_PeriodTable(PC),A0
ADD.L D1,A0
MOVEQ #0,D1
MOVE.W n_period(A6),D1
MOVEQ #36,D7
mt_arploop
MOVE.W (A0,D0.W),D2
CMP.W (A0),D1
BHS.S mt_Arpeggio4
ADDQ.L #2,A0
DBRA D7,mt_arploop
RTS
mt_Arpeggio4
MOVE.W D2,6(A5)
RTS
mt_FinePortaUp
TST.B mt_counter
BNE.S mt_Return2
MOVE.B #$0F,mt_LowMask
mt_PortaUp
MOVEQ #0,D0
MOVE.B n_cmdlo(A6),D0
AND.B mt_LowMask(PC),D0
MOVE.B #$FF,mt_LowMask
SUB.W D0,n_period(A6)
MOVE.W n_period(A6),D0
AND.W #$0FFF,D0
CMP.W #113,D0
BPL.S mt_PortaUskip
AND.W #$F000,n_period(A6)
OR.W #113,n_period(A6)
mt_PortaUskip
MOVE.W n_period(A6),D0
AND.W #$0FFF,D0
MOVE.W D0,6(A5)
RTS
mt_FinePortaDown
TST.B mt_counter
BNE mt_Return2
MOVE.B #$0F,mt_LowMask
mt_PortaDown
CLR.W D0
MOVE.B n_cmdlo(A6),D0
AND.B mt_LowMask(PC),D0
MOVE.B #$FF,mt_LowMask
ADD.W D0,n_period(A6)
MOVE.W n_period(A6),D0
AND.W #$0FFF,D0
CMP.W #856,D0
BMI.S mt_PortaDskip
AND.W #$F000,n_period(A6)
OR.W #856,n_period(A6)
mt_PortaDskip
MOVE.W n_period(A6),D0
AND.W #$0FFF,D0
MOVE.W D0,6(A5)
RTS
mt_SetTonePorta
MOVE.L A0,-(SP)
MOVE.W (A6),D2
AND.W #$0FFF,D2
MOVEQ #0,D0
MOVE.B n_finetune(A6),D0
MULU #37*2,D0
LEA mt_PeriodTable(PC),A0
ADD.L D0,A0
MOVEQ #0,D0
mt_StpLoop
CMP.W (A0,D0.W),D2
BHS.S mt_StpFound
ADDQ.W #2,D0
CMP.W #37*2,D0
BLO.S mt_StpLoop
MOVEQ #35*2,D0
mt_StpFound
MOVE.B n_finetune(A6),D2
AND.B #8,D2
BEQ.S mt_StpGoss
TST.W D0
BEQ.S mt_StpGoss
SUBQ.W #2,D0
mt_StpGoss
MOVE.W (A0,D0.W),D2
MOVE.L (SP)+,A0
MOVE.W D2,n_wantedperiod(A6)
MOVE.W n_period(A6),D0
CLR.B n_toneportdirec(A6)
CMP.W D0,D2
BEQ.S mt_ClearTonePorta
BGE mt_Return2
MOVE.B #1,n_toneportdirec(A6)
RTS
mt_ClearTonePorta
CLR.W n_wantedperiod(A6)
RTS
mt_TonePortamento
MOVE.B n_cmdlo(A6),D0
BEQ.S mt_TonePortNoChange
MOVE.B D0,n_toneportspeed(A6)
CLR.B n_cmdlo(A6)
mt_TonePortNoChange
TST.W n_wantedperiod(A6)
BEQ mt_Return2
MOVEQ #0,D0
MOVE.B n_toneportspeed(A6),D0
TST.B n_toneportdirec(A6)
BNE.S mt_TonePortaUp
mt_TonePortaDown
ADD.W D0,n_period(A6)
MOVE.W n_wantedperiod(A6),D0
CMP.W n_period(A6),D0
BGT.S mt_TonePortaSetPer
MOVE.W n_wantedperiod(A6),n_period(A6)
CLR.W n_wantedperiod(A6)
BRA.S mt_TonePortaSetPer
mt_TonePortaUp
SUB.W D0,n_period(A6)
MOVE.W n_wantedperiod(A6),D0
CMP.W n_period(A6),D0
BLT.S mt_TonePortaSetPer
MOVE.W n_wantedperiod(A6),n_period(A6)
CLR.W n_wantedperiod(A6)
mt_TonePortaSetPer
MOVE.W n_period(A6),D2
MOVE.B n_glissfunk(A6),D0
AND.B #$0F,D0
BEQ.S mt_GlissSkip
MOVEQ #0,D0
MOVE.B n_finetune(A6),D0
MULU #36*2,D0
LEA mt_PeriodTable(PC),A0
ADD.L D0,A0
MOVEQ #0,D0
mt_GlissLoop
CMP.W (A0,D0.W),D2
BHS.S mt_GlissFound
ADDQ.W #2,D0
CMP.W #36*2,D0
BLO.S mt_GlissLoop
MOVEQ #35*2,D0
mt_GlissFound
MOVE.W (A0,D0.W),D2
mt_GlissSkip
MOVE.W D2,6(A5) ; Set period
RTS
mt_Vibrato
MOVE.B n_cmdlo(A6),D0
BEQ.S mt_Vibrato2
MOVE.B n_vibratocmd(A6),D2
AND.B #$0F,D0
BEQ.S mt_vibskip
AND.B #$F0,D2
OR.B D0,D2
mt_vibskip
MOVE.B n_cmdlo(A6),D0
AND.B #$F0,D0
BEQ.S mt_vibskip2
AND.B #$0F,D2
OR.B D0,D2
mt_vibskip2
MOVE.B D2,n_vibratocmd(A6)
mt_Vibrato2
MOVE.B n_vibratopos(A6),D0
LEA mt_VibratoTable(PC),A4
LSR.W #2,D0
AND.W #$001F,D0
MOVEQ #0,D2
MOVE.B n_wavecontrol(A6),D2
AND.B #$03,D2
BEQ.S mt_vib_sine
LSL.B #3,D0
CMP.B #1,D2
BEQ.S mt_vib_rampdown
MOVE.B #255,D2
BRA.S mt_vib_set
mt_vib_rampdown
TST.B n_vibratopos(A6)
BPL.S mt_vib_rampdown2
MOVE.B #255,D2
SUB.B D0,D2
BRA.S mt_vib_set
mt_vib_rampdown2
MOVE.B D0,D2
BRA.S mt_vib_set
mt_vib_sine
MOVE.B 0(A4,D0.W),D2
mt_vib_set
MOVE.B n_vibratocmd(A6),D0
AND.W #15,D0
MULU D0,D2
LSR.W #7,D2
MOVE.W n_period(A6),D0
TST.B n_vibratopos(A6)
BMI.S mt_VibratoNeg
ADD.W D2,D0
BRA.S mt_Vibrato3
mt_VibratoNeg
SUB.W D2,D0
mt_Vibrato3
MOVE.W D0,6(A5)
MOVE.B n_vibratocmd(A6),D0
LSR.W #2,D0
AND.W #$003C,D0
ADD.B D0,n_vibratopos(A6)
RTS
mt_TonePlusVolSlide
BSR mt_TonePortNoChange
BRA mt_VolumeSlide
mt_VibratoPlusVolSlide
BSR.S mt_Vibrato2
BRA mt_VolumeSlide
mt_Tremolo
MOVE.B n_cmdlo(A6),D0
BEQ.S mt_Tremolo2
MOVE.B n_tremolocmd(A6),D2
AND.B #$0F,D0
BEQ.S mt_treskip
AND.B #$F0,D2
OR.B D0,D2
mt_treskip
MOVE.B n_cmdlo(A6),D0
AND.B #$F0,D0
BEQ.S mt_treskip2
AND.B #$0F,D2
OR.B D0,D2
mt_treskip2
MOVE.B D2,n_tremolocmd(A6)
mt_Tremolo2
MOVE.B n_tremolopos(A6),D0
LEA mt_VibratoTable(PC),A4
LSR.W #2,D0
AND.W #$001F,D0
MOVEQ #0,D2
MOVE.B n_wavecontrol(A6),D2
LSR.B #4,D2
AND.B #$03,D2
BEQ.S mt_tre_sine
LSL.B #3,D0
CMP.B #1,D2
BEQ.S mt_tre_rampdown
MOVE.B #255,D2
BRA.S mt_tre_set
mt_tre_rampdown
TST.B n_vibratopos(A6)
BPL.S mt_tre_rampdown2
MOVE.B #255,D2
SUB.B D0,D2
BRA.S mt_tre_set
mt_tre_rampdown2
MOVE.B D0,D2
BRA.S mt_tre_set
mt_tre_sine
MOVE.B 0(A4,D0.W),D2
mt_tre_set
MOVE.B n_tremolocmd(A6),D0
AND.W #15,D0
MULU D0,D2
LSR.W #6,D2
MOVEQ #0,D0
MOVE.B n_volume(A6),D0
TST.B n_tremolopos(A6)
BMI.S mt_TremoloNeg
ADD.W D2,D0
BRA.S mt_Tremolo3
mt_TremoloNeg
SUB.W D2,D0
mt_Tremolo3
BPL.S mt_TremoloSkip
CLR.W D0
mt_TremoloSkip
CMP.W #$40,D0
BLS.S mt_TremoloOk
MOVE.W #$40,D0
mt_TremoloOk
MOVE.W D0,8(A5)
MOVE.B n_tremolocmd(A6),D0
LSR.W #2,D0
AND.W # $ 8 ð # L # d ÿö P